home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / xulrunner / python / autoupdate.py < prev    next >
Encoding:
Python Source  |  2007-11-12  |  4.8 KB  |  131 lines

  1. # Miro - an RSS based video player application
  2. # Copyright (C) 2005-2007 Participatory Culture Foundation
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  17.  
  18. import prefs
  19. import config
  20. import dialogs
  21. import logging
  22. import eventloop
  23. import feedparser
  24.  
  25. from httpclient import grabURL
  26. from gtcache import gettext as _
  27.  
  28. delegate = None
  29. checkInProgress = False
  30.  
  31. # Pass in a connection to the frontend
  32. def setDelegate(newDelegate):
  33.     global delegate
  34.     delegate = newDelegate
  35.  
  36. # Trigger the version checking process
  37. def checkForUpdates(notifyIfUpToDate=False):
  38.     global checkInProgress
  39.     if not checkInProgress:
  40.         checkInProgress = True
  41.         logging.info("Checking for updates...")
  42.         url = config.get(prefs.AUTOUPDATE_URL)
  43.         updateHandler = lambda data: _handleAppCast(data, notifyIfUpToDate)
  44.         errorHandler = _handleError
  45.         grabURL(url, updateHandler, errorHandler)
  46.  
  47. # Error handler
  48. def _handleError(error):
  49.     global checkInProgress
  50.     checkInProgress = False
  51.     logging.warn("HTTP error while checking for updates")
  52.     eventloop.addTimeout (86400, checkForUpdates, "Check for updates")
  53.  
  54. # Handle appcast data when it's correctly fetched
  55. def _handleAppCast(data, notifyIfUpToDate):
  56.     try:
  57.         try:
  58.             appcast = feedparser.parse(data['body'])
  59.             if appcast['bozo'] == '1':
  60.                 return
  61.  
  62.             upToDate = True
  63.             latest = _getItemForLatest(appcast)
  64.             if latest is not None:
  65.                 serial = int(config.get(prefs.APP_SERIAL))
  66.                 upToDate = (serial >= _getItemSerial(latest))
  67.         
  68.             if not upToDate:
  69.                 logging.info('New update available.')
  70.                 if hasattr(delegate, 'handleNewUpdate'):
  71.                     delegate.handleNewUpdate(latest)
  72.                 else:
  73.                     _handleNewUpdate(latest)
  74.             elif notifyIfUpToDate:
  75.                 logging.info('Up to date. Notifying')
  76.                 _handleUpToDate()
  77.             else:
  78.                 logging.info('Up to date.')
  79.         except:
  80.             logging.warn("Error while handling appcast data.")
  81.             import traceback; traceback.print_exc()
  82.     finally:
  83.         global checkInProgress
  84.         checkInProgress = False
  85.         eventloop.addTimeout (86400, checkForUpdates, "Check for updates")
  86.  
  87. # Filter out non platform items, sort remaining from latest to oldest and return
  88. # the item corresponding to the latest known version.
  89. def _getItemForLatest(appcast):
  90.     platform = config.get(prefs.APP_PLATFORM)
  91.     rejectedItems = list()
  92.     for item in appcast['entries']:
  93.         rejectedEnclosures = list()
  94.         for enclosure in item['enclosures']:
  95.             if enclosure['dtv:platform'] != platform:
  96.                 rejectedEnclosures.append(enclosure)
  97.         for enclosure in rejectedEnclosures:
  98.             item['enclosures'].remove(enclosure)
  99.         if len(item['enclosures']) == 0:
  100.             rejectedItems.append(item)
  101.     for item in rejectedItems:
  102.         appcast['entries'].remove(item)
  103.  
  104.     try:
  105.         appcast['entries'].sort(key=_getItemSerial, reverse=True)
  106.         return appcast['entries'][0]
  107.     except:
  108.         return None
  109.  
  110. # Returns the serial of the first enclosure of the passed item
  111. def _getItemSerial(item):
  112.     return int(item['enclosures'][0]['dtv:serial'])
  113.  
  114. # A new update is available, deal with it.
  115. def _handleNewUpdate(item):
  116.     url = item['enclosures'][0]['href']
  117.     def callback(dialog):
  118.         global delegate
  119.         if dialog.choice == dialogs.BUTTON_DOWNLOAD:
  120.             delegate.openExternalURL(url)
  121.     summary = _("%s Version Alert") % (config.get(prefs.SHORT_APP_NAME), )
  122.     message = _("A new version of %s is available. Would you like to download it now?") % (config.get(prefs.LONG_APP_NAME), )
  123.     dlog = dialogs.ChoiceDialog(summary, message, dialogs.BUTTON_DOWNLOAD, dialogs.BUTTON_CANCEL)
  124.     dlog.run(callback)
  125.  
  126. # We are up to date, notify user.
  127. def _handleUpToDate():
  128.     title = _('%s Version Check') % (config.get(prefs.SHORT_APP_NAME), )
  129.     message = _('%s is up to date.') % (config.get(prefs.LONG_APP_NAME), )
  130.     dialogs.MessageBoxDialog(title, message).run()
  131.